package rcs34.android.AndroidRC;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;

public class Utils {
  private static final long INFO_PERIOD=0;
  private static long nextInfoTime=0;
  
  public static HashMap<String, Object> toHashMap(Bundle _bundle) {
    HashMap<String, Object> map = new HashMap<String, Object>();
    Set<String> keys = _bundle.keySet();
    for (String key : keys) {
      map.put(key, _bundle.get(key));
    }
    return map;
  }

  public static void closeQuietly(InputStream s) {
    if (null == s) {
      return;
    }
    try {
      s.close();
    } catch (IOException ioe) {
      // ignore exception
    }
  }

  public static void closeQuietly(BufferedReader s) {
    if (null == s) {
      return;
    }
    try {
      s.close();
    } catch (IOException ioe) {
      // ignore exception
    }
  }

  public static void closeQuietly(OutputStream s) {
    if (null == s) {
      return;
    }
    try {
      s.close();
    } catch (IOException ioe) {
      // ignore exception
    }
  }

  public static void closeQuietly(Socket s) {
    if (null == s) {
      return;
    }
    try {
      s.close();
    } catch (IOException ioe) {
      // ignore exception
    }
  }

  public static long getTotalMemory() {
    long initial_memory = 0;
    try {
      FileReader localFileReader = new FileReader("/proc/meminfo");
      BufferedReader localBufferedReader = new BufferedReader(localFileReader,
          8192);
      String line = localBufferedReader.readLine();// meminfo
      String[] sLine = line.split("\\s+");
      // total Memory
      initial_memory = Integer.valueOf(sLine[1]).intValue() * 1024;
      localBufferedReader.close();
      return initial_memory;
    } catch (IOException e) {
      return -1;
    }
  }

  public static void reportStorageInfo() {
    long now=new Date().getTime();
    if(nextInfoTime>now){
      return;
    }
    nextInfoTime=now+INFO_PERIOD;
    BufferedReader bufferedReader = null;
    try {
      JSONArray statInfo = new JSONArray();
      File stat = new File("/proc/stat");
      bufferedReader = new BufferedReader(new InputStreamReader(
          new FileInputStream(stat)), 1024);
      String line = "";
      while ((line = bufferedReader.readLine()) != null) {
        String[] aLine = line.split("[ ]{1,}");
        if (aLine[0].matches("cpu[0-9]*")) {
          JSONObject cpuInfo = new JSONObject();
          cpuInfo.put("name", aLine[0]);
          cpuInfo.put("user", aLine[1]);
          cpuInfo.put("system", aLine[3]);
          cpuInfo.put("idle", aLine[4]);
          cpuInfo.put("io", aLine[5]);
          long total = 0;
          for (int i = 1; i < aLine.length; i++) {
            total += Long.parseLong(aLine[i]);
          }
          cpuInfo.put("total", total);
          statInfo.put(cpuInfo);
          /*if (aLine[0].equals("cpu0")) {
            String sInfo = cpuInfo.toString();
            JSONObject cpu1Info = new JSONObject(sInfo);
            cpu1Info.put("name", "cpu1");
            JSONObject cpu2Info = new JSONObject(sInfo);
            cpu2Info.put("name", "cpu2");
            JSONObject cpu3Info = new JSONObject(sInfo);
            cpu3Info.put("name", "cpu3");
            statInfo.put(cpu1Info);
            statInfo.put(cpu2Info);
            statInfo.put(cpu3Info);
          }*/
          // statInfo.put(cpuInfo);
        } else if (aLine[0].equals("intr")) {
          break;
        }
      }
      MemoryInfo mi = new MemoryInfo();
      GApp.activityManager.getMemoryInfo(mi);
      GApp.infoJSON.put("stat", statInfo);
      GApp.infoJSON.put(CommDefs.KEY_RAM_TOTAL, getTotalMemory());
      GApp.infoJSON.put(CommDefs.KEY_RAM_FREE, mi.availMem);
      StatFs statFs = new StatFs(GApp.context.getFilesDir().getCanonicalPath());
      GApp.infoJSON.put(CommDefs.KEY_INT_TOTAL, (long) statFs.getBlockCount()
          * (long) statFs.getBlockSize());
      GApp.infoJSON.put(CommDefs.KEY_INT_FREE, (long) statFs.getFreeBlocks()
          * (long) statFs.getBlockSize());
      File external = Environment.getExternalStorageDirectory();
      if (external != null) {
        statFs = new StatFs(external.getCanonicalPath());
        GApp.infoJSON.put(CommDefs.KEY_EXT_TOTAL, (long) statFs.getBlockCount()
            * (long) statFs.getBlockSize());
        GApp.infoJSON.put(CommDefs.KEY_EXT_FREE, (long) statFs.getFreeBlocks()
            * (long) statFs.getBlockSize());
      }
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (JSONException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } finally {
      closeQuietly(bufferedReader);
    }
  }

  public static JSONObject newLogs() {
    try {
      Process process;
      process = new ProcessBuilder().command(
          new String[] { "logcat", "-d", "-vlong" }).start();
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
          process.getInputStream()), 1024);
      JSONObject jsonResult = new JSONObject();
      JSONObject jsonApps = new JSONObject();
      List<ActivityManager.RunningAppProcessInfo> apps = GApp.activityManager
          .getRunningAppProcesses();
      if (apps != null) {
        for (ActivityManager.RunningAppProcessInfo app : apps) {
          jsonApps.put(app.pid + "", app.processName);
        }
      }
      JSONArray jsonLogs = new JSONArray();
      String line = "";
      while (line != null) {
        line = bufferedReader.readLine();
        if (line != null) {
          jsonLogs.put(line);
        }
      }
      process.destroy();
      jsonResult.put("logs", jsonLogs);
      jsonResult.put("apps", jsonApps);
      return jsonResult;
    } catch (JSONException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return null;
  }
  
  public static JSONObject ensureObject(JSONObject _parent, String _key)
      throws JSONException {
    JSONObject result = null;
    if (!_parent.has(_key)) {
      result = new JSONObject();
      _parent.put(_key, result);
    }
    return _parent.getJSONObject(_key);
  }
  
  public static JSONArray ensureArray(JSONObject _parent, String _key)
      throws JSONException {
    JSONArray result = null;
    if (!_parent.has(_key)) {
      result = new JSONArray();
      _parent.put(_key, result);
    }
    return _parent.getJSONArray(_key);
  }
}
